from cv2.gapi.streaming import timestamp
from flask import Flask, Blueprint, jsonify, request
import cv2
import math
import time
import numpy as np


class QrcodeQualityDetector:
    DETECTIONS_NUMBERS = 10  # 选择检测次数
    SELECT_CAMERA = 1  # 选择摄像头
    SELECT_QR_LOCATION = 0  # 选择二维码位置
    SAVE_IMAGE_FILE = 'frame.bmp'  # 保存图片文件
    OBJECT_DETECTION_MODEL1 = 'detect.prototxt'  # 物体检测的模型1
    OBJECT_DETECTION_MODEL2 = 'detect.caffemodel'  # 物体检测的模型2
    IMAGE_RESOLUTION_MODEL1 = 'sr.prototxt'  # 图像超分辨率的模型1
    IMAGE_RESOLUTION_MODEL2 = 'sr.caffemodel'  # 图像超分辨率的模型2

    # 定义变量
    def __init__(self):
        self.array_data_list = []  # 保存二维码坐标
        self.res = "没有获取到二维码信息"  # 用于保存二维码信息
        self.state = ""  # 用于保存质检状态
        self.is_pass = False  # 用于保存质检是否成功
        self.qrcode_is_black = True
        self.enable_write_image = False

    def initialization(self):
        self.array_data_list = []  # 保存二维码坐标
        self.res = "没有获取到二维码信息"  # 用于保存二维码信息
        self.state = ""  # 用于保存质检状态
        self.is_pass = False  # 用于保存质检是否成功

    def set_qrcode_is_black(self, qrcode_is_black):
        self.qrcode_is_black = qrcode_is_black

    # 返回质检信息
    def get_state(self):
        return self.state

    # 获取图片并根据QR码颜色修改图片
    def __get_image(self):
        self.state = "正在读取图像"
        cap = cv2.VideoCapture(self.SELECT_CAMERA)  # 选择使用的摄像头
        if cap is not None:
            # 读取一帧图像
            ret, frame = cap.read()
            if ret:
                return frame

        else:
            # 无法打开摄像头或读取图像
            print("无法打开摄像头或读取图像")
        # 关闭摄像头资源
        cap.release()

    # QR码模型的识别
    def __detect_and_decode(self, frame):
        detect_obj = cv2.wechat_qrcode_WeChatQRCode(self.OBJECT_DETECTION_MODEL1, self.OBJECT_DETECTION_MODEL2,
                                                    self.IMAGE_RESOLUTION_MODEL1,
                                                    self.IMAGE_RESOLUTION_MODEL2)  # 使用的二维码识别模型
        self.state = "正在确定二维码位置"
        # 使用模型获取图片中二维码的内容和位置
        res, points = detect_obj.detectAndDecode(frame)

        # 如果检测到二维码内容
        if res:
            self.res = res
            self.is_pass = True
            self.array_data_list = points[self.SELECT_QR_LOCATION].tolist()

    def doing(self):
        self.state = "准备开始质检"  # 初始化质检状态
        for _ in range(self.DETECTIONS_NUMBERS):
            frame = self.__get_image()
            if frame is not None:
                # 成功读取到图像
                if self.enable_write_image:
                    cv2.imwrite(self.SAVE_IMAGE_FILE, frame)

                if not self.qrcode_is_black:
                    # 反转图像颜色
                    frame = cv2.bitwise_not(frame)

                self.__detect_and_decode(frame)
                self.state = "正在分析质检信息"
                if self.is_pass:
                    self.state = "正在返回质检信息"
                    break
                else:
                    continue
            else:
                continue
        return self.array_data_list, self.res, self.is_pass


class QrcodeQualityDetectorServer:
    BLUEPRINT_NAME = 'qrcode_quality'

    def __init__(self):
        self.quality_detector = QrcodeQualityDetector()
        self.qrcode_quality_bp = Blueprint(self.BLUEPRINT_NAME, __name__)
        self.qrcode_quality_bp.route('/process_image', methods=['GET'])(self.process_image)
        self.qrcode_quality_bp.route('/process_image_data', methods=['GET'])(self.process_image_data)
        self.qrcode_quality_bp.route('/state', methods=['GET'])(self.get_state)
        self.qrcode_quality_bp.route('/set_qrcode_color', methods=['GET'])(self.set_qrcode_color)
        self.qrcode_quality_bp.route('/verify_link', methods=['GET'])(self.verify_link)
        self.app = Flask(self.BLUEPRINT_NAME)
        if self.app is not None:
            self.app.register_blueprint(self.qrcode_quality_bp)
            self.app.run(host='0.0.0.0', port=5000)

    def verify_link(self):
        try:
            verify_link = True
            response_data = {'verify_link': verify_link}
            return jsonify(response_data)

        except Exception as e:
            return jsonify({'error': str(e)})

    def set_qrcode_color(self):
        try:
            qrcode_is_black = request.args.get('qrcode_is_black')
            qrcode_is_black = qrcode_is_black.lower() == 'true'
            self.quality_detector.set_qrcode_is_black(qrcode_is_black)

            return jsonify({'success': True})  # Returning a valid response
        except Exception as e:
            return jsonify({'error': str(e)})

    def process_image(self):
        try:

            array_data_list, res, is_pass = self.quality_detector.doing()
            self.quality_detector.initialization()
            response_data = {'is_pass': is_pass}
            return jsonify(response_data)

        except Exception as e:
            return jsonify({'error': str(e)})

    def process_image_data(self):
        try:
            array_data_list, res, is_pass = self.quality_detector.doing()
            self.quality_detector.initialization()
            response_data = {'position_correct': array_data_list, 'info': res}
            return jsonify(response_data)

        except Exception as e:
            return jsonify({'error': str(e)})

    def get_state(self):
        self.quality_detector.initialization()
        return self.quality_detector.get_state()


if __name__ == '__main__':
    quality_detector_server = QrcodeQualityDetectorServer()
